/**
 * Created on : 2015/11/28
 * Author     : @kankan
 */

/************************************************************************************************************************
 ******************************************************** xtreetable ****************************************************
 ************************************************************************************************************************/
// create xtreetable object
var xtreetable = xtreetable || {};

(function() {

    /**************************************************
     * XTreeTable
     **************************************************/
    var XTreeTable = function(obj, options) {
		var self = this;
		
		self.$obj = obj;								// 加了$只是为了区分Js变量而已，可以用来表示这个变量是一个jquery对象，没其他含义
		self.$options = options;
		self.$elem = null;
		self.$index = 0;								// 递归计数用，“全局变量”，模拟静态变量
		
		self._init();
    };
    
    XTreeTable.prototype = {
        /* 初始化 */
        _init: function() {
            var self = this;
            
            self._preProcess();
            self._createDomElem();
			self._bindEvent();
            self._show();
            
            return self;								// VERY IMPORTANT!!! 这样才能继续调用后面的其它方法
        },
        
        /* 预处理 */
        _preProcess: function() {
            var self = this;
            
            self.$options = $.extend({}, XTreeTable.DEFAULTS, self.$options);		// 将调用者的参数与本对象的默认参数进行合并
            // 获取数据
            if (self.$options.url) {
            	var request = $.extend({}, self.$options.ajaxOptions, {
	                method: self.$options.method,
	            	url: self.$options.url,
	                data: self.$options.params,
	                async: false,
	                success: function(data) {
	                	self._execLoadFunc('onLoadSuccess', data);
	                	
	                    if (self.$options.ajaxDataFilter && typeof self.$options.ajaxDataFilter === 'function') {
	                    	self.$options.data = self.$options.ajaxDataFilter(data);
	                    } else {
	                    	self.$options.data = data;
	                	}
	                },
	                error: function(XMLHttpRequest, textStatus) {
	                    self._execLoadFunc('onLoadError', XMLHttpRequest, textStatus);				// +++
	                },
	                complete: function() {
//	                    if (!silent) {										// 增加加载显示功能，待完善+++
//	                        that.$tableLoading.hide();
//	                    }
	                }
	            });
	            $.ajax(request);
            }
        },
        
        /* 构建HTML */
        _createDomElem: function() {
            var self = this;
			var thead = $('<thead></thead>');
			var tbody = $('<tbody></tbody>');

			self.$elem = $('<div></div>');
            thead.append(self._createTHeadTr());
            tbody.append(self._createTBodyTr(self.$options.data, 0, 0));
            self.$elem.append(thead).append(tbody);
        },
        
        /* _createTHead */
        _createTHeadTr: function() {
            var self = this;
			var tempTr = $('<tr></tr>');

			for (var j = 0; j < self.$options.columns.length; j++) {
				var title = self.$options.columns[j].title;
				var tempTd = $('<th style="width:' + self.$options.columns[j].width + ';">' + title + '</th>');
				tempTr.append(tempTd);
    		}
			if (tempTr.html() != '') {
	    		return tempTr;
			}
    		return null;
		},

        /* JSON递归动态生成树 */
        _createTBodyTr: function(data, pid, deep) {
            var self = this;
			var holder = $('<div></div>');
			
        	if (data != null) {
    			for (var i = 0; i < data.length; i++) {
    				if (data[i].pid == pid) {
    					var tempTr = $('<tr></tr>');
					//	tempTr.attr('data-index', self.$index);
						tempTr.attr('data-id', data[i].id);
						tempTr.attr('data-pid', data[i].pid);

    					for (var j = 0; j < self.$options.columns.length; j++) {
    						var tempTd = $('<td style="width:' + self.$options.columns[j].width + ';"></td>');
    						var field = self.$options.columns[j].field;

							if (j == self.$options.column) {
								var btn = $('<i class="field"></i>');
								btn.attr('style', 'margin-left:' + deep * 20 + 'px;margin-right:10px;');
								tempTd.prepend(btn);
							}
							
    						if (self.$options.columns[j].formatter && typeof self.$options.columns[j].formatter === 'function') {
    							var str = self.$options.columns[j].formatter(data[i][field], data[i], self.$index);
    							tempTd.append(str);
    						} else {
        						tempTd.append(data[i][field]);
    						}
							
        					tempTr.append(tempTd);
    					}

    					self.$index++;
						holder.append(tempTr);
						var barTr = this._createTBodyTr(data, data[i].id, deep + 1);
						if (barTr != '') {					// 如果有下级元素
							holder.children().last().find('.field').addClass(self.$options.expandedClass).addClass("expended").css('cursor', 'pointer');
						} else {
							holder.children().last().find('.field').addClass(self.$options.leafClass);
						}
    					holder.append(barTr);
    				}
    			}
    		}
			return holder.html();
        },

        /* 绑定事件 */
        _bindEvent: function() {
			var self = this;
			
			/* 绑定图标点击事件 */
			$(document).off('click', '.field').on('click', '.field', function() {
				var trId = $(this).closest('tr').attr('data-id');
				
				if (!$(this).hasClass(self.$options.leafClass)) {				// 这个地方有个BUG，即必须设置叶子节点的类样式，否则此处代码失效
					if (!$(this).hasClass("expended")) {						// 没展开，则开
						$(this).addClass("expended").removeClass(self.$options.collapsedClass).addClass(self.$options.expandedClass);
						$('tr[data-pid=' + trId + ']').show();
					} else {													// 有展开，则收
						self._collapseNode(trId, true);
					}			
				}	
			});
		},

		_collapseNode: function(trId, operFlag) {
			var self = this;
			var node = $('tr[data-id=' + trId + ']').find('i');
			var trs = $('tr[data-pid=' + trId + ']');
			
			if (!node.hasClass(self.$options.leafClass)) {
				if (operFlag) {
					node.removeClass("expended").removeClass(self.$options.expandedClass).addClass(self.$options.collapsedClass);
					trs.hide();
				} else {
					node.addClass("expended").removeClass(self.$options.collapsedClass).addClass(self.$options.expandedClass);
					trs.show();
				}
			}
			for (var i = 0; i <trs.length; i++) {
				self._collapseNode($(trs[i]).attr('data-id'), operFlag);
			}
		},
        
        /* 执行加载方法 */
        _execLoadFunc: function(type, data, textStatus) {
            var self = this;
            if (self.$options[type] && typeof self.$options[type] === 'function') {
                self.$options[type](data, textStatus);
            }
        },

        /* 执行方法 */
        _execFunc: function(type) {
            var self = this;
            if (self.$options[type] && typeof self.$options[type] === 'function') {
                self.$options[type](self);
            }
        },
        
        /* _show */
        _show: function() {
            var self = this;
            $(self.$obj).empty().append(self.$elem.html());
            self._execFunc('afterShow');
        },
        
        /****** 4 outer ******/
        /* expandAll */
        expandAll: function() {
            var self = this;
			var trs = $('tr[data-pid=0]');
			for (var i = 0; i <trs.length; i++) {
                self._collapseNode($(trs[i]).attr('data-id'), false);
            }
        },
        
        /* collapseAll */
        collapseAll: function() {
            var self = this;
			var trs = $('tr[data-pid=0]');
			for (var i = 0; i <trs.length; i++) {
                self._collapseNode($(trs[i]).attr('data-id'), true);
            }
        },
        
        /* refresh */
        refresh: function() {
            var self = this;
        	this._init();
        }
    };

    XTreeTable.DEFAULTS = {
    	url					: '',
    	method      		: 'GET',
        cache				: true,
        contentType			: 'application/json',
        dataType			: 'json',
        ajaxOptions			: {},
    	params          	: {},
    	onLoadSuccess		: null,
    	onLoadError			: null,
    	ajaxDataFilter		: null,
    	afterShow			: null,
    	data				: '',
    	columns          	: [],
    	column          	: 0,
		collapsedClass		: 'fa fa-folder-o',
		expandedClass		: 'fa fa-folder-open-o',
		leafClass			: 'fa fa-file-o',
    };

    /** xtreetable */
	xtreetable = function(obj, options) {
		return new XTreeTable(obj, options);
    };
    xtreetable.defaults = XTreeTable.DEFAULTS;
    
})();